package com.jack.payment.service.basic.impl;

import com.jack.payment.constant.ResultHintConstant;
import com.jack.payment.dao.user.*;
import com.jack.payment.entity.common.BusinessException;
import com.jack.payment.entity.generate.user.*;
import com.jack.payment.util.common.StringUtil;
import com.jack.payment.util.common.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.security.SecureRandom;
import java.util.Base64;

@Service
public class UserSettingServiceImpl {
    private Logger log = LoggerFactory.getLogger(UserSettingServiceImpl.class);


    @Autowired
    private UserApiDao userApiDao;
    @Autowired
    private UserSettingDao userSettingDao;
    @Autowired
    private UserAuthDao userAuthDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserDeviceDao userDeviceDao;


    /**
     * 生成一个新的api Key
     * @return
     */
    public String generateNewUserApiKey() {
        StringBuilder resultKey = new StringBuilder();
        while (true) {
            SecureRandom random = new SecureRandom();
            byte[] keyBytes = new byte[32];
            random.nextBytes(keyBytes);
            String apiKey = Base64.getEncoder().encodeToString(keyBytes);
            UserApiModel userApiModel = userApiDao.getAppointApiExist(null, apiKey, 1);
            if (userApiModel == null) {
                resultKey.append(apiKey);
                break;
            }
        }
        return resultKey.toString();
    }

    /**
     * 该用户的api 密钥是否存在
     * @param apiKey
     * @param enable
     * @return
     */
    public UserApiModel getAppointUserApiKey(String apiKey, Integer enable) throws BusinessException {
        if (StringUtil.isEmpty(apiKey)) {
            throw new BusinessException(ResultHintConstant.BASIC_DATA_DROP);
        }
        UserApiModel userApiModel = userApiDao.getAppointApiExist(null, apiKey, enable);
        if (userApiModel == null) {
            log.warn("未查询到对应的ApiKey: " + apiKey);
            throw new BusinessException(ResultHintConstant.DATA_NOT_EXIST);
        }
        return userApiModel;
    }


    /**
     * 根据id 查询出api Key
     * @param id
     * @return
     * @throws BusinessException
     */
    public UserApiModel getAppointIdApiKey(String id) throws BusinessException {
        UserApiModel userApiModel = userApiDao.getAppointApiExist(id, null, 1);
        if (userApiModel == null) {
            log.warn("未查询到对应的ApiKey: " + id);
            throw new BusinessException(ResultHintConstant.DATA_NOT_EXIST);
        }
        return  userApiModel;
    }

    /**
     * 修改用户api 值
     * @param userApiModel
     */
    public void updateUserApiModel(UserApiModel userApiModel) {
        userApiDao.updateUserApiKeyInfo(userApiModel);
    }

    /**
     *
     * @param userDeviceModel
     */
    public void unbindUserDeviceStatus(UserDeviceModel userDeviceModel) {
        userDeviceDao.updateUserDeviceInfo(userDeviceModel);
    }


    /**
     * 给用户生成一个新的api 密钥
     * @param userApiModel
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void generateNewApiKeyRecord(UserApiModel userApiModel) {
        userApiDao.insertUserApiKeyInfo(userApiModel);
    }


    /**
     * 重新 设置 或 换 2fa 登录方式
     * @param userModel
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void updateNew2FALonginSecret(UserModel userModel) {
        userDao.updateUserBasicInfo(userModel);
    }


    /**
     * 修改用户基础信息
     * @param userSettingModel
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void updateUserBasicInfo(UserSettingModel userSettingModel) {
        userSettingDao.updateAppointUserSetting(userSettingModel);
    }

    /**
     * 修改用户登录密码
     * @param userModel
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void updateUserLoginPwd(UserModel userModel) {
        userDao.updateUserBasicInfo(userModel);
    }

    /**
     * 解除账号的三方绑定信息
     * @param channel
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void unbindAuthLoginMethod(Integer channel,
                                      UserModel userModel) {
        userDao.updateUserBasicInfo(userModel);
        userAuthDao.unbindUserAuth(userModel.getId(), 0, channel, TimeUtil.getCurrentTime());
    }

    /**
     * 更换 账号的三方登录
     * @param userAuthModel
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void bindAuthLoginMethod(UserAuthModel userAuthModel, UserModel userModel) {
        userAuthDao.unbindUserAuth(
                userAuthModel.getId(),
                0,
                userAuthModel.getChannel(),
                userAuthModel.getCreateTime());
        userAuthDao.insertUserAuth(userAuthModel);
        userDao.updateUserBasicInfo(userModel);
    }

    /**
     * 绑定账号的基础登录方式
     * @param userModel
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void bindAccountBasicLoginMethod(UserModel userModel) {
        userDao.updateUserBasicInfo(userModel);
    }
}
